#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
配置管理模块

提供GitLab TimescaleDB包的配置管理功能，包括：
- 环境变量读取
- 配置文件解析
- 默认配置设置
- 日志配置
"""

import os
import sys
from dataclasses import dataclass, field
from pathlib import Path
from typing import Dict, Optional

from loguru import logger

# 导入TimescaleDBManager

# 加载环境变量
try:
    from dotenv import load_dotenv

    # 查找.env文件，优先查找当前目录，然后查找父目录
    env_file = Path('.env')
    if not env_file.exists():
        env_file = Path(__file__).parent.parent / '.env'

    if env_file.exists():
        load_dotenv(env_file)
        logger.info(f"✅ 已加载环境变量文件: {env_file}")
    else:
        logger.warning("⚠️ 未找到.env文件，使用默认配置")
except ImportError:
    logger.warning("⚠️ python-dotenv未安装，无法加载.env文件")


@dataclass
class GitLabInstanceConfig:
    """单个GitLab实例配置"""
    url: str = "https://gitlab.com"
    access_token: str = ""
    timeout: int = 30
    retry_count: int = 3
    retry_delay: int = 1
    name: str = "default"  # 实例名称，用于标识


@dataclass
class GitLabConfig:
    """GitLab配置（支持多实例）"""
    instances: Dict[str, GitLabInstanceConfig] = field(default_factory=dict)
    default_instance: str = "default"  # 默认使用的实例名称

    def __post_init__(self):
        # 如果没有配置实例，创建默认实例
        if not self.instances:
            self.instances["default"] = GitLabInstanceConfig()

    def get_default_instance(self) -> GitLabInstanceConfig:
        """获取默认实例配置"""
        return self.instances.get(self.default_instance, GitLabInstanceConfig())

    def add_instance(self, name: str, url: str, access_token: str, **kwargs) -> None:
        """添加GitLab实例"""
        self.instances[name] = GitLabInstanceConfig(
            url=url,
            access_token=access_token,
            name=name,
            **kwargs
        )


@dataclass
class DatabaseConfig:
    """数据库配置"""
    connection_string: str = "postgresql://postgres:water@10.48.0.85:5432/gitlab_stats"
    min_connections: int = 1
    max_connections: int = 10
    connection_timeout: int = 30
    query_timeout: int = 300


@dataclass
class SyncConfig:
    """同步配置"""
    batch_size: int = 100
    max_workers: int = 5
    full_sync: bool = False
    include_merge_commits: bool = True
    sync_interval_hours: int = 24
    max_commits_per_request: int = 1000


@dataclass
class LogConfig:
    """日志配置"""
    level: str = "INFO"
    format: str = "{time:YYYY-MM-DD HH:mm:ss} | {level} | {name}:{function}:{line} | {message}"
    file_path: Optional[str] = None
    max_file_size: str = "10 MB"
    backup_count: int = 5
    console_output: bool = True


@dataclass
class AppConfig:
    """应用配置"""
    gitlab: GitLabConfig = field(default_factory=GitLabConfig)
    database: DatabaseConfig = field(default_factory=DatabaseConfig)
    sync: SyncConfig = field(default_factory=SyncConfig)
    log: LogConfig = field(default_factory=LogConfig)
    debug: bool = False
    environment: str = "production"


def get_config() -> AppConfig:
    """获取应用配置"""
    config = AppConfig()

    # GitLab配置 - 支持多实例
    # 首先加载默认实例配置（向后兼容）
    default_instance = GitLabInstanceConfig(
        url=os.getenv('GITLAB_URL', 'https://gitlab.com'),
        access_token=os.getenv('GITLAB_ACCESS_TOKEN', ''),
        timeout=int(os.getenv('GITLAB_TIMEOUT', '30')),
        retry_count=int(os.getenv('GITLAB_RETRY_COUNT', '3')),
        retry_delay=int(os.getenv('GITLAB_RETRY_DELAY', '1')),
        name='default'
    )
    config.gitlab.instances['default'] = default_instance

    # 加载多实例配置（从环境变量）
    # 格式: GITLAB_INSTANCES=instance1_name:url:token,instance2_name:url:token
    instances_env = os.getenv('GITLAB_INSTANCES', '')
    if instances_env:
        for instance_str in instances_env.split(','):
            parts = instance_str.strip().split(':')
            if len(parts) >= 3:
                # 重新组装URL，处理协议部分
                name = parts[0]
                # 如果URL包含协议，需要重新组装
                if len(parts) >= 4 and parts[1] in ['http', 'https']:
                    # 处理包含端口号的情况: name:http://host:port:token
                    if len(parts) == 5:
                        url = f"{parts[1]}:{parts[2]}:{parts[3]}"
                        token = parts[4]
                    else:
                        # 不包含端口号: name:http://host:token
                        url = f"{parts[1]}:{parts[2]}"
                        token = parts[3]
                else:
                    url = parts[1]
                    token = parts[2]
                config.gitlab.add_instance(name, url, token)

    # 设置默认实例
    config.gitlab.default_instance = os.getenv('GITLAB_DEFAULT_INSTANCE', 'default')

    # 数据库配置
    config.database.connection_string = os.getenv('DATABASE_URL', config.database.connection_string)
    config.database.min_connections = int(os.getenv('DB_MIN_CONNECTIONS', str(config.database.min_connections)))
    config.database.max_connections = int(os.getenv('DB_MAX_CONNECTIONS', str(config.database.max_connections)))
    config.database.connection_timeout = int(
        os.getenv('DB_CONNECTION_TIMEOUT', str(config.database.connection_timeout)))
    config.database.query_timeout = int(os.getenv('DB_QUERY_TIMEOUT', str(config.database.query_timeout)))

    # 同步配置
    config.sync.batch_size = int(os.getenv('SYNC_BATCH_SIZE', str(config.sync.batch_size)))
    config.sync.max_workers = int(os.getenv('SYNC_MAX_WORKERS', str(config.sync.max_workers)))
    config.sync.full_sync = os.getenv('SYNC_FULL_SYNC', 'false').lower() == 'true'
    config.sync.include_merge_commits = os.getenv('SYNC_INCLUDE_MERGE_COMMITS', 'true').lower() == 'true'
    config.sync.sync_interval_hours = int(os.getenv('SYNC_INTERVAL_HOURS', str(config.sync.sync_interval_hours)))
    config.sync.max_commits_per_request = int(
        os.getenv('SYNC_MAX_COMMITS_PER_REQUEST', str(config.sync.max_commits_per_request)))

    # 日志配置
    config.log.level = os.getenv('LOG_LEVEL', config.log.level)
    config.log.format = os.getenv('LOG_FORMAT', config.log.format)
    config.log.file_path = os.getenv('LOG_FILE_PATH', config.log.file_path)
    config.log.max_file_size = os.getenv('LOG_MAX_FILE_SIZE', config.log.max_file_size)
    config.log.backup_count = int(os.getenv('LOG_BACKUP_COUNT', str(config.log.backup_count)))
    config.log.console_output = os.getenv('LOG_CONSOLE_OUTPUT', 'true').lower() == 'true'

    # 应用配置
    config.debug = os.getenv('DEBUG', 'false').lower() == 'true'
    config.environment = os.getenv('ENVIRONMENT', config.environment)

    return config


def setup_logging(log_config: Optional[LogConfig] = None) -> None:
    """设置日志配置"""
    if log_config is None:
        log_config = get_config().log

    # 移除默认处理器
    logger.remove()

    # 控制台输出
    if log_config.console_output:
        logger.add(
            sys.stdout,
            level=log_config.level,
            format=log_config.format,
            colorize=True
        )

    # 文件输出
    if log_config.file_path:
        logger.add(
            log_config.file_path,
            level=log_config.level,
            format=log_config.format,
            rotation=log_config.max_file_size,
            retention=log_config.backup_count,
            compression="zip",
            encoding="utf-8"
        )

    logger.info(f"日志系统初始化完成，级别: {log_config.level}")


def validate_config(config: AppConfig) -> bool:
    """验证配置"""
    errors = []

    # 验证GitLab配置
    default_instance = config.gitlab.get_default_instance()
    if not default_instance.access_token:
        errors.append("GitLab访问令牌未设置")

    if not default_instance.url:
        errors.append("GitLab URL未设置")

    # 验证数据库配置
    if not config.database.connection_string:
        errors.append("数据库连接字符串未设置")

    if config.database.min_connections <= 0:
        errors.append("数据库最小连接数必须大于0")

    if config.database.max_connections < config.database.min_connections:
        errors.append("数据库最大连接数必须大于等于最小连接数")

    # 验证同步配置
    if config.sync.batch_size <= 0:
        errors.append("批处理大小必须大于0")

    if config.sync.max_workers <= 0:
        errors.append("最大工作线程数必须大于0")

    # 输出错误信息
    if errors:
        for error in errors:
            logger.error(f"配置验证失败: {error}")
        return False

    logger.info("配置验证通过")
    return True


def print_config(config: AppConfig) -> None:
    """打印配置信息（隐藏敏感信息）"""
    logger.info("=== 应用配置 ===")
    logger.info(f"环境: {config.environment}")
    logger.info(f"调试模式: {config.debug}")

    logger.info("=== GitLab配置 ===")
    default_instance = config.gitlab.get_default_instance()
    logger.info(f"URL: {default_instance.url}")
    logger.info(f"访问令牌: {'*' * 10 if default_instance.access_token else '未设置'}")
    logger.info(f"超时时间: {default_instance.timeout}秒")
    logger.info(f"重试次数: {default_instance.retry_count}")
    logger.info(f"重试延迟: {default_instance.retry_delay}秒")

    logger.info("=== 数据库配置 ===")
    # 隐藏密码
    db_url = config.database.connection_string
    if '@' in db_url:
        parts = db_url.split('@')
        if len(parts) >= 2:
            user_pass = parts[0].split('//')[-1]
            if ':' in user_pass:
                user = user_pass.split(':')[0]
                db_url = db_url.replace(user_pass, f"{user}:***")

    logger.info(f"连接字符串: {db_url}")
    logger.info(f"连接池: {config.database.min_connections}-{config.database.max_connections}")
    logger.info(f"连接超时: {config.database.connection_timeout}秒")
    logger.info(f"查询超时: {config.database.query_timeout}秒")

    logger.info("=== 同步配置 ===")
    logger.info(f"批处理大小: {config.sync.batch_size}")
    logger.info(f"最大工作线程: {config.sync.max_workers}")
    logger.info(f"全量同步: {config.sync.full_sync}")
    logger.info(f"包含合并提交: {config.sync.include_merge_commits}")
    logger.info(f"同步间隔: {config.sync.sync_interval_hours}小时")
    logger.info(f"单次最大提交数: {config.sync.max_commits_per_request}")

    logger.info("=== 日志配置 ===")
    logger.info(f"日志级别: {config.log.level}")
    logger.info(f"控制台输出: {config.log.console_output}")
    logger.info(f"文件输出: {config.log.file_path or '未设置'}")
    if config.log.file_path:
        logger.info(f"文件大小限制: {config.log.max_file_size}")
        logger.info(f"备份文件数: {config.log.backup_count}")


# 默认配置实例
default_config = get_config()
